﻿partial class Program
{
    static async Task LoadModulesTest()
    {
        var opList = LoadModules();
        foreach (var item in opList)
        {
            //await op.CommonModuleTest();
            if (item is ICommonModuleClient op)
            {
                await op.CommonModuleTest();
            }
        }
    }

    static List<IGrpcOp> LoadModules()
    {
        List<IGrpcOp> modules = [];
        var pluginDirList = Directory.GetDirectories("plugins");
        foreach (var dir in pluginDirList)
        {
            var entryDll = Directory.GetFiles(dir, "gRPCDemo*.dll").FirstOrDefault();
            if (entryDll == null) continue;
            var assembly = LoadAssembly(entryDll);
            var types = assembly.GetExportedTypes();
            foreach (var type in types)
            {
                if (typeof(IGrpcOp).IsAssignableFrom(type) && Activator.CreateInstance(type) is IGrpcOp instance) modules.Add(instance);
            }
        }
        return modules;
    }
    private static Assembly LoadAssembly(string path)
    {
        var dir = Path.GetDirectoryName(path) ?? throw new ArgumentException("path的父目录异常！", nameof(path));
        // 创建一个程序集加载上下文
        var context = new AssemblyLoadContext(Guid.NewGuid().ToString());
        // 注册事件，当开始加载指定目录下的程序集时会触发
        context.Resolving += (context, assemblyName) =>
        {
            // 在加载入口程序集所依赖的其它程序集时，指定目录进行加载。
            using var stream = File.OpenRead(Path.Combine(dir, $"{assemblyName.Name}.dll"));
            return context.LoadFromStream(stream);
        };
        // 通过流方式加载插件入口程序集gRPCDemo.dll
        using var stream = File.OpenRead(path);
        return context.LoadFromStream(stream);
    }
}
